package main.leetcode.clockin.Auguest;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

/**
 * 841. 钥匙和房间
 *
 * <p>有 N 个房间，开始时你位于 0 号房间。每个房间有不同的号码：0，1，2，...，N-1，并且房间里可能有一些钥匙能使你进入下一个房间。
 *
 * <p>在形式上，对于每个房间 i 都有一个钥匙列表 rooms[i]，每个钥匙 rooms[i][j] 由 [0,1，...，N-1] 中的一个整数表示，其中 N = rooms.length。
 * 钥匙 rooms[i][j] = v 可以打开编号为 v 的房间。
 *
 * <p>最初，除 0 号房间外的其余所有房间都被锁住。
 *
 * <p>你可以自由地在房间之间来回走动。
 *
 * <p>如果能进入每个房间返回 true，否则返回 false。
 *
 * <p>示例 1：<br>
 * 输入: [[1],[2],[3],[]] <br>
 * 输出: true <br>
 * 解释: <br>
 * 我们从 0 号房间开始，拿到钥匙 1。 <br>
 * 之后我们去 1 号房间，拿到钥匙 2。 <br>
 * 然后我们去 2 号房间，拿到钥匙 3。<br>
 * 最后我们去了 3 号房间。 <br>
 * 由于我们能够进入每个房间，我们返回 true。
 *
 * <p>示例 2：<br>
 * 输入：[[1,3],[3,0,1],[2],[0]] <br>
 * 输出：false <br>
 * 解释：我们不能进入 2 号房间。
 *
 * <p>提示： <br>
 * 1 <= rooms.length <= 1000 <br>
 * 0 <= rooms[i].length <= 1000 <br>
 * 所有房间中的钥匙数量总计不超过 3000。
 */
public class day31 {
    /** 广度优先遍历 */
    public boolean canVisitAllRooms(List<List<Integer>> rooms) {
        int n = rooms.size();
        boolean[] isArrived = new boolean[n];
        Queue<List<Integer>> queue = new LinkedList<>();
        queue.offer(rooms.get(0));
        isArrived[0] = true;
        int cnt = 1;
        while (!queue.isEmpty()) {
            List<Integer> list = queue.poll();
            for (Integer i : list) {
                if (isArrived[i]) {
                    continue;
                }
                ++cnt;
                isArrived[i] = true;
                queue.offer(rooms.get(i));
            }
        }
        return cnt == n;
    }

    //    /** 深度优先遍历 */
    //    private int cnt;
    //
    //    public boolean canVisitAllRooms(List<List<Integer>> rooms) {
    //        int n = rooms.size();
    //        boolean[] isArrived = new boolean[n];
    //        dfs(0, isArrived, rooms);
    //        return cnt == n;
    //    }
    //
    //    private void dfs(int i, boolean[] isArrived, List<List<Integer>> rooms) {
    //        if (isArrived[i]) {
    //            return;
    //        }
    //        isArrived[i] = true;
    //        ++cnt;
    //        for (Integer integer : rooms.get(i)) {
    //            dfs(integer, isArrived, rooms);
    //        }
    //    }
}
